
using System;
using System.Text;
using Microsoft.Extensions.Configuration;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;

namespace IotS.MessageServiceTest
{
    public class SubService : IDisposable
    {
        private readonly MSSettings _settings;
        private readonly IConnection _connection;
        private readonly IModel _channel;
        private EventingBasicConsumer _consumer;

        public SubService()
        {
            _settings = Program.Configuration.Get<MSSettings>();

            var factory = new ConnectionFactory
            {
                HostName = _settings.RabbitMQ.Host,
                UserName = _settings.RabbitMQ.UserName,
                Password = _settings.RabbitMQ.Password
            };
            factory.AutomaticRecoveryEnabled = true;

            _connection = factory.CreateConnection();
            _channel = _connection.CreateModel();
        }

        public void Dispose()
        {
            if (_channel.IsOpen)
            {
                _channel.Close();
                _channel.Dispose();
            }
            if (_connection.IsOpen)
            {
                _connection.Close();
                _connection.Dispose();
            }
        }

        public void Start()
        {
            InitQueue();

            Console.WriteLine(" Waiting for messages.");

            _channel.BasicConsume(_settings.RabbitMQ.QueueName, false, consumer: _consumer);
        }

        private void InitQueue()
        {
            _channel.QueueDeclare(_settings.RabbitMQ.QueueName, true, false, true, null);
            _channel.ExchangeDeclare(_settings.RabbitMQ.ExchangeName, ExchangeType.Fanout);
            _channel.QueueBind(_settings.RabbitMQ.QueueName, _settings.RabbitMQ.ExchangeName, "");
            _channel.BasicQos(0, 1, false);

            _consumer = new EventingBasicConsumer(_channel);

            _consumer.Received += Received;
        }

        private void Received(object sender, BasicDeliverEventArgs e)
        {
            var body = e.Body;
            var message = Encoding.UTF8.GetString(body);

            Console.WriteLine($" Recevied -> {message}");

            _channel.BasicAck(e.DeliveryTag, false);
        }
    }
}